home *** CD-ROM | disk | FTP | other *** search
- /*
- * tcplist.c - make list of tcp connections, making use of rfc931 services
- * if available.
- *
- * tcplist attempts to be efficient about rfc931 queries, using
- * the following techniques:
- * - all connections to a particular host are grouped together.
- * - connections to the rfc931 service on different hosts are
- * made simultaneously, where available file descriptors allow,
- * using non-blocking I/O.
- * - if the rfc931 service on a host is not available, no further
- * requests will be made to that host.
- * - if the rfc931 service supports multiple queries per service
- * connection, tcplist will take advantage of this.
- *
- * Author: John DiMarco, University of Toronto, CDF
- * jdd@cdf.toronto.edu
- */
-
- #ifndef lint
- static char rcsid[] = "$Header: /u/jdd/src/jdd/distrib/tcplist/RCS/tcplist.c,v 1.9 1993/05/26 00:15:17 jdd Exp $";
- #endif
-
- #include "patchlevel.h"
-
- /*
- * $Log: tcplist.c,v $
- * Revision 1.9 1993/05/26 00:15:17 jdd
- * Release 1.1
- *
- * Revision 1.9 1993/05/26 00:09:08 jdd
- * Release 1.1
- *
- * Revision 1.8 1993/05/25 18:07:33 jdd
- * misc fixes
- * Added -f option, to allow specifying a file with hosts not to rfc931-query.
- * In an environment with many X-terminals and a limited number of file
- * descriptors, this can dramatically speed up tcplist by reducing the
- * number of rfc931 query passes that are required.
- *
- * Revision 1.7 1993/05/20 01:07:52 jdd
- * Release 1.0
- *
- * Revision 1.6 1993/05/19 22:31:22 jdd
- * didn't check for failed getpwuid. Fixed.
- *
- * Revision 1.4 1993/05/17 23:01:08 jdd
- * misc fixes
- *
- * Revision 1.3 1992/10/16 19:50:04 jdd
- * Port to IRIX 4.x
- * Reworked rfc931 section to handle running out of file descriptors.
- *
- * Revision 1.3 1992/10/16 19:46:17 jdd
- * port to IRIX
- *
- * Revision 1.2 1992/10/09 21:48:56 jdd
- * complete rewrite of rfc931 stuff to use non-blocking I/O.
- * 30 secs max timeout for all rfc931 calls, and all done in parallel,
- * to improve performance.
- *
- * Revision 1.1 1992/07/30 00:10:24 jdd
- * Initial revision
- *
- # Revision 1.1 1991/08/15 23:24:10 jdd
- # Initial revision
- #
- */
-
- #define PORT_ANY 0
-
- #include <stdio.h>
- #include <errno.h>
- #include <ctype.h>
- #include <nlist.h>
- #include <pwd.h>
- #include <signal.h>
- #include <syslog.h>
-
- #ifdef HAVE_KVM
- #include <kvm.h>
- #else
- #include "kvm.h"
- #endif
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/param.h>
- #include <sys/ioctl.h>
- #include <sys/socket.h>
- #include <sys/protosw.h>
- #include <sys/domain.h>
- #include <sys/socketvar.h>
-
- #ifdef IRIX
- #define _KERNEL
- #else
- #define KERNEL
- #endif
-
- #include <sys/file.h>
-
- #if defined(IRIX) || defined(MIPS)
- #include <sys/inode.h>
- #include <sys/fstyp.h>
- #include <sys/fsid.h>
- #endif
-
- #include <fcntl.h>
- #include <sys/user.h>
- #include <sys/wait.h>
-
-
- #ifdef IRIX
- #undef _KERNEL
- #else
- #undef KERNEL
- #endif
-
-
- #include <netdb.h>
- #include <net/if.h>
- #include <net/route.h>
- #include <netinet/in.h>
- #include <netinet/in_pcb.h>
- #include <netinet/tcp.h>
- #include <netinet/ip_var.h>
- #include <netinet/tcp_timer.h>
- #include <netinet/tcp_var.h>
- #include <arpa/inet.h>
-
- #ifdef MIPS
- #include <sys/var.h>
- extern int errno;
- #endif
-
- #include "utils.h"
-
- void identhosts();
- void doidenthosts();
- struct hostent *gethostbyaddr();
- struct servent *getservbyport();
- #ifdef MIPS
- struct passwd *getpwuid();
- #endif
-
- #define TERSEFORMAT "%s@%s:%s %s@%s:%s\n"
- #define TABULARFORMAT "%-9s%-22s%-9s%-9s%-22s%-9s\n"
-
- /* rfc931 port */
- #define PORT 113
-
- /* rfc931 query timeout */
- #define TIMEOUT 30
-
- /* identhosts status codes */
- #define UNKNOWN -1
- #define BAD 0
- #define GOOD 1
-
- #ifndef NOIDENT
- #define NOIDENT "/dev/null"
- #endif /* ndef NOIDENT */
-
- #define NOIDSIZ 512 /* no more than NOIDSIZ hosts to skip rfc931 id for */
- #define INBUFSIZ 80
- u_long noid[NOIDSIZ]; /* NOIDENT table */
- int ni=0; /* index into noid */
- char *noidfile = NULL;
-
- #if defined(IRIX) || defined(MIPS)
-
- struct nlist nl[] = {
- #define N_FILE 0
- { "file" },
- #define N_V 1
- { "v" },
- { "" },
- };
-
- #else
- struct nlist nl[] = {
- #define N_FILE 0
- { "_file" },
- #define N_NFILE 1
- { "_nfile" },
- { "" },
- };
- #endif
-
- kvm_t *kd;
-
- /* linked list of connections: local and remote ports, and remote id */
- struct connection {
- short remote; /* remote port on query'd machine */
- short local; /* local port on query'ed machine */
- char *ident; /* rfc931 ident string, if available */
- char *user; /* local user ident string */
- struct connection *next;
- };
-
- /* linked list of hosts, each with a list of connections to it */
- struct hostlist {
- long addr; /* internet address of host */
- struct connection *conn; /* linked list of connections */
- int identstatus; /* rfc931 identification status? */
- int sock; /* rfc931 socket */
- struct hostlist *next;
- } *hlist = NUL(struct hostlist *);
-
- char *progname;
- int d;
-
- int hostresolv = TRUE;
- int servresolv = TRUE;
- int servershow = FALSE;
- int printheader = FALSE;
-
- void getkvm();
- char *InAddrToString();
- char *PNumToString();
-
-
- void usage()
- {
- (void)fprintf(stderr, "Usage: %s [-n][-N][-s][-T][-f filename]\n",
- progname);
- (void)exit(2);
- }
-
- struct file *filetable;
- int nfiles;
-
- int ulongcmp(i, j)
- u_long *i, *j;
- {
- return(*i-*j);
- }
-
- /*
- * main - parse arguments and handle options
- */
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int c, i;
- int errflg = 0;
- extern int optind;
- extern char *optarg;
- long addr;
- char *localhost = NULL;
- u_long localaddr;
- char *format = TERSEFORMAT;
-
- #if defined(IRIX) || defined (MIPS)
- struct var v;
- int socket_index;
-
- socket_index = sysfs(GETFSIND, FSID_SOCKET);
- #endif
-
- progname = argv[0];
- while ((c = getopt(argc, argv, "dnNsTf:")) != EOF)
- switch (c) {
- case 'd':
- ++d;
- break;
- case 'n':
- hostresolv = FALSE;
- break;
- case 'N':
- servresolv = FALSE;
- break;
- case 's':
- servershow = TRUE;
- break;
- case 'T':
- format=TABULARFORMAT;
- printheader = TRUE;
- break;
- case 'f':
- noidfile = optarg;
- break;
- default:
- errflg++;
- break;
- }
- if (errflg) {
- usage();
- }
-
- /* read in the hosts not to rfc931-query */
- {
- FILE *fp;
- char buf[INBUFSIZ];
-
- if(NULL==noidfile) noidfile=NOIDENT;
- fp=efopen(noidfile, "r");
- while(NULL!=fgets(buf, INBUFSIZ, fp)){
- struct hostent *h;
- if(buf[0]) buf[strlen(buf)-1]='\0'; else continue;
- if('#'==buf[0]) continue; /* skip comments */
- if(-1==(noid[ni]=inet_addr(buf))){
- if(NULL==(h=gethostbyname(buf))){
- Warning("line %d: unknown host %s",
- ni+1, buf);
- ni--;
- } else {
- bcopy(h->h_addr_list[0],
- (char *)&noid[ni], h->h_length);
- }
- }
- ni++;
- #ifdef DEBUG
- if(ni){
- struct in_addr debuga;
- debuga.s_addr=noid[ni-1];
- dfprintf(1, stderr, "noid[%d] is %s\n", ni-1,
- inet_ntoa(debuga));
- }
- #endif /* DEBUG */
- }
- efclose(fp);
- }
- qsort((char *)noid, ni, sizeof(u_long), ulongcmp);
- if(NULL==(kd=kvm_open(NULL, NULL, NULL, O_RDONLY, progname))){
- Error("kvm_open");
- }
- if(0!=kvm_nlist(kd, nl)){
- Error("kvm_nlist: %d", kvm_nlist(kd, nl));
- }
- #if defined(IRIX) || defined(MIPS)
- getkvm(nl[N_V].n_value, &v, sizeof(v));
- nfiles=v.v_file;
- addr=nl[N_FILE].n_value;
- #else
- getkvm(nl[N_NFILE].n_value, &nfiles, sizeof(nfiles));
- getkvm(nl[N_FILE].n_value, &addr, sizeof(addr));
- #endif
- filetable=(struct file *)calloc(nfiles, sizeof(struct file));
- if(NULL==filetable){
- Error("Can't allocate memory for file table.");
- }
- getkvm(addr, filetable, nfiles * sizeof(struct file));
- if(printheader){
- printf(TABULARFORMAT, "LOCAL", "LOCAL", "LOCAL",
- "REMOTE", "REMOTE", "REMOTE");
- printf(TABULARFORMAT, "USER", "HOST", "PORT",
- " USER", " HOST", " PORT");
- printf(TABULARFORMAT, "-----", "-----", "-----",
- "------", "------", "------");
- }
- for(i=0;i<nfiles;i++){
- struct socket so, *sp;
- struct protosw ps;
- struct domain dom;
- struct inpcb pcb;
- #ifdef IRIX
- struct inode inode;
- #else
- struct ucred cred;
- #endif
- struct passwd *pw;
- struct connection *cn;
- struct hostlist *hl;
- int found;
-
- sp=&so;
- #ifdef IRIX
- /* for IRIX, need to check for socket after getting inode */
- if(0!=filetable[i].f_count){
- #else
- if(filetable[i].f_type == DTYPE_SOCKET &&
- 0!=filetable[i].f_count){
- #endif
- int uid;
-
- /* grab the socket out of the kernel. Is it
- * a stream socket? If not, go on. */
- #ifdef IRIX
- getkvm(filetable[i].f_inode, &inode, sizeof(inode));
- if(socket_index != inode.i_fstyp) continue;
-
- getkvm(soc_fsptr(&inode), &so, sizeof(struct socket));
- #else
- getkvm(filetable[i].f_data, sp, sizeof(struct socket));
- #endif
- if(sp->so_type!=SOCK_STREAM) continue;
- /* now get the protosw. */
- getkvm(sp->so_proto, &ps, sizeof(ps));
- /* ... and its domain. go on if not internet. */
- getkvm(ps.pr_domain, &dom, sizeof(dom));
- if(dom.dom_family!=AF_INET) continue;
- /* If we've gotten this far, it's a tcp socket. Let's
- * get the protocol control block... */
- if(0==sp->so_pcb) continue;
- getkvm(sp->so_pcb, &pcb, sizeof(pcb));
- /* (but if foreign addr is ANY, this is a server, so
- * if we don't want servers, stop here.) */
- if(!servershow){
- if(INADDR_ANY == pcb.inp_faddr.s_addr) continue;
- }
- /* ...and the user id */
- #ifdef IRIX
- uid=inode.i_uid;
- #else /* IRIX */
- getkvm(filetable[i].f_cred, &cred, sizeof(cred));
- uid=cred.cr_ruid;
- #endif /* IRIX */
- pw=getpwuid(uid);
- if(NULL==pw){
- pw=new(struct passwd);
- pw->pw_name=mem(10);
- sprintf(pw->pw_name, "#%d", uid);
- pw->pw_uid=uid;
- }
- #ifdef DEBUG
- dfprintf(3, stderr, "user id is %d and user is %s\n",
- uid, pw->pw_name);
- #endif /* DEBUG */
-
- /* is this host already on the hostlist? */
- found = FALSE;
- for(hl=hlist;NULL!=hl;hl=hl->next){
- if(pcb.inp_faddr.s_addr == hl->addr){
- /* found it */
- found = TRUE;
- break;
- }
- }
- if(!found){
- /* create new hostlist entry */
- hl=new(struct hostlist);
- hl->addr = pcb.inp_faddr.s_addr;
- hl->conn = NUL(struct connection *);
- hl->next = hlist;
- hlist = hl;
- }
- /* create new connection entry */
- cn=new(struct connection);
- cn->remote=pcb.inp_fport;
- cn->local=pcb.inp_lport;
- cn->user=s(pw->pw_name);
- cn->next=hl->conn;
- hl->conn=cn;
- if(NULL==localhost) {
- /*
- * assumption: localhost will always be the
- * same for all connections. Is this wise?
- */
- localaddr=pcb.inp_laddr.s_addr;
- localhost=s(InAddrToString(localaddr));
- }
- }
- }
- identhosts(hlist); /* do rfc931 stuff */
- {
- /* print out results */
-
- struct connection *cn;
- struct hostlist *hl;
- char *remotehost, *remoteport, *localport, *remoteuser;
-
- for(hl=hlist;NULL!=hl;hl=hl->next){
- for(cn=hl->conn;NULL!=cn;cn=cn->next){
- /* for each connection, print line */
-
- /* localhost constant for all, already known */
- remotehost=s(InAddrToString(hl->addr));
- localport=s(PNumToString(cn->local,
- localaddr));
- remoteport=s(PNumToString(cn->remote,
- hl->addr));
- remoteuser=cn->ident;
- if(NULL==remoteuser) remoteuser="?";
- printf(format, cn->user, localhost,
- localport, remoteuser,
- remotehost, remoteport);
- }
- }
- }
- exit(0);
- }
-
- /*
- * InAddrToString(): Convert internet address to a.b.c.d numeric string or
- * hostname. If hostresolv, try to find internet address,
- * otherwise use numeric form only.
- */
- char *InAddrToString(iaddr)
- u_long iaddr;
- {
- static char iaddrbuff[16];
- struct hostent *h;
-
- if(INADDR_ANY == iaddr){
- sprintf(iaddrbuff, "*");
- } else {
- if(hostresolv){
- h=gethostbyaddr((char *)&iaddr,
- sizeof(iaddr), AF_INET);
- if(h) return (h->h_name);
- }
- sprintf(iaddrbuff, "%u.%u.%u.%u", (iaddr>>24)&0xff,
- (iaddr>>16)&0xff, (iaddr>>8)&0xff,
- iaddr&0xff);
- }
- return(iaddrbuff);
- }
-
- /*
- * PNumToString(): Convert port numbers to string. Successive calls overwrite.
- * "tcp" assumed. Resolve to service name if servresolv.
- */
- char *PNumToString(pnum, host)
- u_short pnum;
- u_long host;
- {
- static char pnumbuff[16];
- struct servent *sv;
-
- if(PORT_ANY == pnum){
- sprintf(pnumbuff, "*");
- } else {
- if(servresolv){
- sv=getservbyport((int)pnum, "tcp");
- if(sv){
- return(sv->s_name);
- }
- }
- sprintf(pnumbuff, "%u", (unsigned int)pnum);
- }
- return(pnumbuff);
- }
-
- /*
- * getkvm(): get something from kernel memory. Assumes "kd" is a valid
- * descriptor from kvm_open.
- */
- void getkvm(addr, buf, len)
- long addr;
- char *buf;
- int len;
- {
- /* get something from kernel memory */
- if(0>kvm_read(kd, addr, buf, len)){
- Error("getkvm: kvm_read(%08x, %d)", addr, len);
- }
- }
-
- /*
- * identhosts(): use the rfc931 service, where available, to fill in ident
- * field of the connection lists in hostlist. This takes
- * advantage, where available, of daemons (eg. pidentd) that can
- * answer several queries per connection, which is a performance
- * win, although not strictly rfc931 compliant.
- *
- * Restrictions: long identstrings may be lost, since identhosts
- * is lazy and only does one read.
- */
- void identhosts(hosts)
- struct hostlist *hosts;
- {
- int numdescs;
- int num = 0;
- struct hostlist *ih, *sav, *undone;
-
- numdescs = getdtablesize() - 10;
- ih=undone=hosts;
-
- /* do identhosts in batches of MAX_FILE_DESCRIPTORS - 10, to
- eliminate risk of running out of file descriptors. */
-
- while(NULL!=ih){
- for(;NULL!=ih && num<numdescs;ih=ih->next){
- if(NULL==bsearch((char *)&(ih->addr), (char *)noid, ni,
- sizeof(u_long), ulongcmp)){
- ih->identstatus = UNKNOWN;
- num++;
- } else {
- ih->identstatus = BAD;
- }
- }
- if(NULL!=ih){
- sav=ih->next;
- ih->next=NULL;
- doidenthosts(undone);
- num=0;
- ih->next=undone=sav;
- }
- }
- doidenthosts(undone);
- }
-
- void doidenthosts(hosts)
- struct hostlist *hosts;
- {
- long maxfd;
- struct connection *ic;
- struct hostlist *ih;
- int r;
- int port=htons(PORT);
- fd_set wds;
- int num=0, decided=0;
- struct timeval timeout;
- #ifdef DEBUG
- struct in_addr debuga;
- #endif
-
- if(0>(maxfd=ulimit(4,0l))){
- perror("ulimit");
- exit(2);
- }
-
- /* waltz through the connections in the hostlist, setting idents */
- /* to NULL */
-
- for(ih=hosts;NULL!=ih;ih=ih->next){
- for(ic=ih->conn;NULL!=ic;ic=ic->next){
- ic->ident = NULL;
- }
- if(UNKNOWN==ih->identstatus) num++;
- }
- #ifdef DEBUG
- dfprintf(1, stderr, "Doidenthosts: num=%d\n", num);
- #endif
-
- /* get sockets */
- for(ih=hosts;NULL!=ih;ih=ih->next){
- if(ih->identstatus==BAD) continue; /* skip known-BAD hosts */
- if(0>(ih->sock=socket(AF_INET,SOCK_STREAM, 0))){
- perror("socket");
- }
- /* turn on non-blocking I/O */
- (void)fcntl(ih->sock, F_SETFL, FNDELAY);
- }
-
- /* start connects on all of them */
- for(ih=hosts;NULL!=ih;ih=ih->next){
- struct sockaddr_in sa;
-
- if(BAD==ih->identstatus){
- /*
- * this host has been found on the noident list. Don't
- * bother with connect.
- */
- #ifdef DEBUG
- debuga.s_addr = ih->addr;
- dfprintf(2, stderr, "Skipping %s\n",
- inet_ntoa(debuga));
- #endif /* DEBUG */
- } else {
- sa.sin_family = AF_INET;
- sa.sin_port = port;
- sa.sin_addr.s_addr = ih->addr;
-
- (void)connect(ih->sock, &sa, sizeof(sa));
- }
- }
-
- while(decided<num){
- timeout.tv_sec = (long)TIMEOUT;
- timeout.tv_usec = 0;
-
- /* make write descriptors list for a select, to */
- /* determine when the connects finish.*/
- FD_ZERO(&wds);
- for(ih=hosts;NULL!=ih;ih=ih->next){
- if(UNKNOWN==ih->identstatus){
- FD_SET(ih->sock,&wds);
- }
- }
-
- if(0>(r=select((int)maxfd, NUL(fd_set *), &wds, NUL(fd_set *),
- &timeout))){
- perror("select");
- exit(2);
- }
-
- if(r==0){
- /* we've timed out. Write off all remaining sockets */
- for(ih=hosts;NULL!=ih;ih=ih->next){
- if(UNKNOWN==ih->identstatus){
- ih->identstatus = BAD;
- }
- }
- break;
- }
-
- for(ih=hosts;NULL!=ih;ih=ih->next){
- if(UNKNOWN==ih->identstatus){
- if(FD_ISSET(ih->sock,&wds)){
- /* connection has completed */
- struct sockaddr_in sa;
-
- sa.sin_family = AF_INET;
- sa.sin_port = port;
- sa.sin_addr.s_addr = ih->addr;
-
- if(-1==connect(ih->sock, &sa,
- sizeof(sa))){
- if(EISCONN==errno){
- ih->identstatus=GOOD;
- } else {
- ih->identstatus=BAD;
- }
- decided++;
- }
- r--;
- if(r<1) break;
- }
- }
- }
- #ifdef DEBUG
- dfprintf(2, stderr, "%d of %d decided\n", decided, num);
- #endif /* DEBUG */
- }
-
- #ifdef DEBUG
- dfprintf(2, stderr, "Results:\n");
- #endif
- for(ih=hosts;NULL!=ih;ih=ih->next){
- /* turn off nonblocking I/O */
- if(GOOD==ih->identstatus) (void)fcntl(ih->sock, F_SETFL, 0);
-
- #ifdef DEBUG
- debuga.s_addr = ih->addr;
-
- switch(ih->identstatus){
- case GOOD:
- dfprintf(2, stderr, "%s good\n",inet_ntoa(debuga));
- break;
- case BAD:
- dfprintf(2, stderr, "%s bad\n",inet_ntoa(debuga));
- break;
- case UNKNOWN:
- dfprintf(2, stderr, "%s unknown\n",inet_ntoa(debuga));
- break;
- default:
- dfprintf(2, stderr, "%s strange status %d\n",
- inet_ntoa(debuga), ih->identstatus);
- break;
- }
- #endif
- }
-
- /* now, for each ok host, send an appropriate request off to the
- rfc931 server */
- for(ih=hosts;NULL!=ih;ih=ih->next){
- char ubuff[1024], osbuff[128];
- int remote, local;
- for(ic=ih->conn;NULL!=ic;ic=ic->next){
- char wbuff[80];
- char rbuff[1024];
- int n;
-
- if(GOOD!=ih->identstatus) continue;
-
- (void)sprintf(wbuff, "%d,%d\n", ic->remote, ic->local);
-
- if(0>=write(ih->sock, wbuff, strlen(wbuff))){
- }
- if(0>(n=read(ih->sock, rbuff, sizeof(rbuff)))){
- (void)close(ih->sock);
- ih->identstatus=BAD;
- break;
- } else if(0==n){
- /* other side may have closed conn, reopen */
- /* and try again. */
- struct sockaddr_in sa;
- #ifdef DEBUG
- dfprintf(3, stderr, "reopening\n");
- #endif
-
- /* close the socket */
- (void)close(ih->sock);
-
- /* get a new socket */
- if(0>(ih->sock=socket(AF_INET,
- SOCK_STREAM, 0))){
- ih->identstatus=BAD;
- break;
- }
-
- /* connect */
- sa.sin_family = AF_INET;
- sa.sin_port = port;
- sa.sin_addr.s_addr = ih->addr;
- if(0>connect(ih->sock,&sa,
- sizeof(sa))){
- ih->identstatus=BAD;
- break;
- }
-
- if(0>write(ih->sock, wbuff, strlen(wbuff))){
- (void)close(ih->sock);
- ih->identstatus=BAD;
- break;
- }
- if(0>(n=read(ih->sock, rbuff, sizeof(rbuff)))){
- (void)close(ih->sock);
- ih->identstatus=BAD;
- break;
- }
- /*
- * Kludge alert:
- * It's not technically correct to be satisfied
- * with just one read here; should probably be
- * reading until buff overflow or newline.
- * This'll miss stuff if remote identd returns
- * too much data.
- */
- if(0==n){
- /* still eof! give up. */
- (void)close(ih->sock);
- ih->identstatus=BAD;
- break;
- }
- }
- rbuff[n]='\0';
- #ifdef DEBUG
- dfprintf(1, stderr, "%lu: %s", ih->addr, rbuff);
- #endif
- /* Check the response */
- if(4>sscanf(rbuff, "%d , %d : USERID : %s : %s",
- &remote, &local, osbuff, ubuff)){
- /* bad response. */
- #ifdef DEBUG
- dfprintf(2, stderr, "bad response %s\n", rbuff);
- #endif
- continue;
- }
- if(ic->local!=local || ic->remote!=remote){
- /* Port number mismatch. */
- #ifdef DEBUG
- dfprintf(2, stderr,
- "port mismatch %s: %d, %d with %d, %d\n",
- rbuff, remote, local, ic->remote,
- ic->local);
- #endif
- continue;
- }
-
- /* It's okay. Trash trailing newline or lf, set ident
- field */
- {
- int sl=strlen(ubuff)-1;
- if(ubuff[sl]=='\n' || ubuff[sl]=='\r'){
- ubuff[sl]='\0';
- }
- }
- ic->ident = s(ubuff);
- #ifdef DEBUG
- dfprintf(2, stderr,
- "Host %lu remote %d local %d user %s\n",
- ih->addr, ic->remote, ic->local, ic->ident);
- #endif
- }
- /* we're done with this host */
- (void)close(ih->sock);
- }
- }
-